package types

import (
	"errors"
	"fmt"
	"time"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/wonderivan/logger"
)

func GetUserStr() string {
	return "user"
}

func JudgeUserTable(companyId int) error {
	// _, err := mysql.CusSql.QueryIdlimit1(GetUserStr(companyId))
	// if err != nil {
	// 	err = createUserTable(companyId)
	// }
	// return err
	return nil
}

func createUserTable() error {
	sql := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s(
		id INT UNSIGNED AUTO_INCREMENT,
		phone char(40) unique,
		email char(40) NOT NULL unique,
		password CHAR(100) NOT NULL,
		name VARCHAR(100) NOT NULL,
		headimg TEXT,
		person_sign CHAR(200),
		handle_sign VARCHAR(1000),
		faceimg TEXT,
		sex int,
		id_card char(18),
		birthday datetime,
		body_height double(4,1),
		body_weight double(4,1),
		nation	varchar(255),
		native_place varchar(255),
		marital_status	varchar(255),
		politics_status	varchar(255),
		health_condition varchar(255),
		blood_type char(10),
		education varchar(255),
		school varchar(255),
		technical_grade varchar(255),
		major varchar(255),
		home_adress varchar(255),
		adress varchar(255),
		time datetime NOT NULL DEFAULT NOW(),
		create_time datetime DEFAULT NOW(),
		update_time datetime DEFAULT NOW() on update NOW(),
		PRIMARY KEY (id)
	)`, GetUserStr())
	logger.Info(sql)
	return nil
}

type UserFrom struct {
	// Id          int    `json:"id" binding:"required"`
	Email            string    `form:"email"`            //用户账号
	Phone            string    `form:"phone"`            //用户手机号
	Userid           int       `form:"userId"`           //用户的ID
	Password         string    `form:"password"`         //用户新密码
	Old_password     string    `form:"old_password"`     //用户旧密码
	Name             string    `form:"name"`             //用户姓名
	Headimg          string    `form:"headimg"`          //用户头像
	Person_sign      string    `form:"person_sign"`      //用户个性签名限制50字内
	Handle_sign      string    `form:"handle_sign"`      //用户手写签名
	Faceimg          string    `form:"faceimg"`          //用户人脸信息
	Id_card          string    `form:"id_card"`          //用户身份证
	Sex              int       `form:"sex"`              //性别 0未设置 1男 2女
	Birthday         time.Time `form:"birthday"`         //生日
	Body_height      float64   `form:"body_height"`      //身高
	Body_weight      float64   `form:"body_weight"`      //体重
	Nation           string    `form:"nation"`           //民族
	Native_place     string    `form:"native_place"`     //籍贯
	Marital_status   string    `form:"Marital_status"`   //婚姻状况
	Politics_status  string    `form:"politics_status"`  //政治面貌
	Health_condition string    `form:"health_condition"` //健康状况
	Blood_type       string    `form:"blood_type"`       //血型
	Education        string    `form:"education"`        //最高学历
	School           string    `form:"school"`           //毕业院校
	Technical_grade  string    `form:"technical_grade"`  //技术等级
	Major            string    `form:"major"`            //专业
	Home_adress      string    `form:"home_adress"`      //户籍所在地
	Adress           string    `form:"adress"`           //地址
}

type LoginForm struct {
	Email         string `form:"email" binding:"required"`
	Password      string `form:"password" binding:"required"`
	Phone         string `form:"phone"`
	Name          string `form:"name"`
	Department_id int    `form:"department_id"`
	Code          string `form:"code"`
	CodeId        string `form:"codeId"`
	Source        string `form:"source"`       // 来源 web_park | web_enterprise | app
	Company_name  string `form:"company_name"` // 公司名称
}

type LoginStruct struct {
	ID       int
	Username string
	Source   string
	jwt.StandardClaims
}

func ParseSign(secret string, tokenString string) (*LoginStruct, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (i interface{}, err error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}
		return []byte(secret), nil
	})

	//err不为空，说明token已过期
	if err != nil {
		return nil, err
	}

	//将获取的token中的Claims强转为MapClaims
	claims, ok := token.Claims.(jwt.MapClaims)
	//判断token是否有效
	if !(ok && token.Valid) {
		return nil, errors.New("cannot convert claim to mapClaim")
	}
	// 验证jwt是否过期
	// if float64(time.Now().Unix()) > (claims["exp"].(float64)) {
	// 	return nil, errors.New("time expiration")

	// }

	//获取payload中的数据

	// id, err = strconv.Atoi()
	info := &LoginStruct{
		ID:       int(claims["id"].(float64)),
		Username: claims["username"].(string),
	}

	if claims["source"] != nil {
		info.Source = claims["source"].(string)
	}
	return info, nil
}

func Sign(info LoginStruct, secret string) (tokenString string, err error) {
	//传入指定的签名方法和payload信息,创建Token对象
	//库中内置了好几种签名方法

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"id":       info.ID,
		"username": info.Username,
		"nbf":      time.Now().Unix(),
		"iat":      time.Now().Unix(),
		"exp":      time.Now().Add(time.Hour * TokenTimeHour * 30).Unix(),
		"source":   info.Source,
	})
	//根据密码生成token字符串
	tokenString, err = token.SignedString([]byte(secret))

	return tokenString, err
}

func SignExp(info LoginStruct, secret string, exp int64) (tokenString string, err error) {
	//传入指定的签名方法和payload信息,创建Token对象
	//库中内置了好几种签名方法
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"id":       info.ID,
		"username": info.Username,
		"nbf":      time.Now().Unix(),
		"iat":      time.Now().Unix(),
		"exp":      exp,
	})
	//根据密码生成token字符串
	tokenString, err = token.SignedString([]byte(secret))
	return tokenString, err
}

const (
	// token过期时间
	TokenTimeHour = 24
	// 刷新token过期时间
	RefreshTokenTimeHour = 36
	// 账号登录次数时间
	AccountExpireTime = time.Minute * 5
	// 默认账号最大登录次数
	DefaultAccountCount = 5
	// 图片宽度
	CodeImgWidth = 160
	// 图片高度
	CodeImgHeight = 60
	// 验证码过期时间
	CodeImgExpireTime = time.Minute * 5
	// CodePrefix
	CodePrefix = "code:"
)
